namespace CL_MLK_ASSIGN {

	namespace bad {
		class C {
		public:
			C() { ip = new int; }
			~C() { delete ip; }
			C& operator=(const C& rhs) {
				if (this == &rhs) return *this;
				ip = new int;
				*ip = *rhs.ip;
				return *this;
			}
		private:
			C(const C&);
			int* ip;
		};

	
	
	}
	namespace good_1 {
		class C {
		public:
			C() { ip = new int; }
			~C() { delete ip; }
			C& operator=(const C& rhs) {
				if (this == &rhs) return *this;
				delete ip;
				ip = new int;
				*ip = *rhs.ip;
				return *this;
			}
		private:
			C(const C&);
			int* ip;
		};
	}

	namespace good_2 {
	
		class counted {
		public:
			counted() { counter = 1; }
			void addRef() { counter++; }
			void decRef() { counter--; if (counter == 0) delete this; }
		private:
			int counter;
		};

		class C {
		public:
			C() { cp = new counted; }
			~C() { cp->decRef(); }
			C& operator=(const C& rhs) {
				if (this == &rhs) return *this;
				cp = rhs.cp;
				cp->addRef();
				return *this;
			}
		private:
			C(const C&);
			counted* cp;
		};
	}

	namespace good_3 {
		class counted {
		public:
			counted() { counter = 1; }
			void addRef() { counter++; }
			void decRef() { counter--; if (counter == 0) delete this; }
			
		private:
			int counter;
			
		};

		class C {
		public:
			C() { cp = new counted(); }
			~C() { cp->decRef(); }
			C& operator=(const C& rhs) {
				if (this == &rhs) return *this;
				cp->decRef();
				cp = rhs.cp;
				cp->addRef();
				return *this;
			}
		private:
			C(const C&);
			counted* cp;
		};
	
	}

	
}